"""
python高级技巧
1.iterator
"""


class Pow2(object):
    def __init__(self, max):
        self.max = max
        self.n = 0

    def __iter__(self):
        self.n = 0
        return self

    def __next__(self):
        if self.n < self.max:
            self.n += 1
            return 2 ** self.n
        else:
            raise StopIteration


p = Pow2(10)
for i in p:
    print(i)

"""
2.python instance method,class method,static method
intance method a = A() a.foo() a.bar()
class method bind class
static method
"""


class A(object):
    @staticmethod
    def s_foo():
        pass

    @classmethod
    def c_foo(cls):
        pass

    def foo(self):
        pass


a = A()
a.foo()
A.c_foo()

"""
3.引用类型
[] {}
深拷贝 浅拷贝
正确如下：
from copy import deepcopy
l1 = []
l2 = deepcopy(l1)
l1.append(1)
print(l2)

错误1如下：
l1 = [1,[1,2],3]
l2 = l1[:]

错误2如下:
def foo(a=[]):
    a.append(1)
    print(a)
foo()
foo()
"""

"""
3. lambda closure closure ref

1. algorithm sort(lambda x : x['key'])
2. map reduce filter
"""
import functools
import operator

mul2 = lambda x: 2 * x
print(mul2(3))

print(list(map(lambda x: 3 * x, [1, 2, 3, 4])))
print(list(filter(lambda x: x % 3 == 0, [1, 2, 3, 4])))
print(functools.reduce(operator.add, [1, 2, 3, 4, 5], 5))

"""
closure
"""

# def greeting(msg):
#     def hello(name):
#         print(msg, name)
#     return hello
#
# h = greeting("welcome")
# h("akira")

# l = []
# for i in range(10):
#     def _(i=i):
#         print(i)
#     l.append(_)
#
# for f in l:
#     f()

"""
4.args kwargs
tuple
dict
*args a,b,c,d
**kwargs k = v
"""


def log(*args, **kwargs):
    print("args", args)
    print("kwargs", kwargs)


log(1, 2, 3, 4)
log(1, 2, [1, 2, 3], c=4)

"""
以下是脚本语言的通用特性
5.
1.list comprehension
[i for i in range(10)]
2.dict comprehension
{k:1 for k in range(10)}
3.list generator
(i for i in range(10))
4.dict generator
5.添加filter method
[i for i in range(10) if i % 2 ==0]
"""

"""
6.decorator
AOP aspect oriential programming
"""


def simple_wrapper(fn):
    def _():
        print(fn.__name__)
        return fn()

    return _


# 固定参数:x
def fix_arg_wrapper(fn):
    def _(x):
        # print(fn.__name__)
        return fn(x)

    return _


# 万能的参数
def all_args_wrapper(fn):
    def _(*args, **kwargs):
        print(*args, **kwargs)
        return fn(*args, **kwargs)

    return _


@simple_wrapper
def foo():
    pass


@all_args_wrapper
def bar(a, b, c):
    pass


foo()
bar(1, 2, 3)

"""
7.magic method：missing method
1.全局访问的控制：
1.1写操作__setattribute__(python3 已删除: l.a =1 )
1.2读操作__getattribute__(l.a)
2.最后的守门员：区别1:触发__getattr__，__setattr__时，类里面一定没有这个成员
__getattr__
__setattr__
"""


# 每次访问属性,会先调用__getattribute(self)
class logAll(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def __getattribute__(self, item):
        print(item)


l = logAll()
print(l.a)
l.b
l.c


class Any(object):
    def __getattr__(self, item):
        print(item)

    def __setattr__(self, key, value):
        print('set', key, value)


a = Any()
# 类没有属性a：触发__getattr__
a.a
# 不仅没有属性a,而且还赋值：会触发__setattr__
a.a = 1


# Any()可以接收任何函数(item)，接收任何参数
class Any(object):
    # 方案1：如果不定义__getattr__：AttributeError: 'Any' object has no attribute 'fuck'
    # pass

    def __getattr__(self, item):
        def _(*args, **kwargs):
            print("function name", item)
            print("args", args)
            print("kwargs", kwargs)

        # setattr：减少__getattr__造成的资源浪费,以后访问快一些
        setattr(self, item, _)

        return _


a = Any()
a.fuck(1, 2, 3)
a.shift(1, 2, [1, 2, 3], c=[])

"""
8.mixin
c ,c++ ,java

b->a 
a->b

a->a interface
a->b interface

mixin
Final(A,B,C)
"""


class A(object):
    def foo(self):
        print("foo")

    def bar(self):
        print("bar")
        self.shit()


class B(object):
    def shit(self):
        print("shit")


class C(A, B):
    pass


c = C()
c.bar()

"""
场景分析：
1.protocal协议
2.rpc
client调用接口,Server远程可以实现
client
    server_client server_client.attrack(xxx)
------>
Server 
    logic.attrack(xxx)
"""

"""
只保留tcpServer和tcpClient即可
"""
